package com.cqrt.util;

import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;

public class WorkdayCalculator {

    // 默认每天工作小时数
    private static final int WORK_HOURS_PER_DAY = 8;
    // 每天工作毫秒数（8小时 * 60分钟 * 60秒 * 1000毫秒）
    private static final long MILLISECONDS_PER_WORKDAY = WORK_HOURS_PER_DAY * 60 * 60 * 1000;

    // 日期时间格式
    public static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    /**
     * 计算两个日期之间的工作日工期（排除周六和周日），返回毫秒值
     * @param startDateStr 计划开始日期字符串（格式：yyyy-MM-dd HH:mm:ss）
     * @param endDateStr 计划结束日期字符串（格式：yyyy-MM-dd HH:mm:ss）
     * @return 工期毫秒值（按每天8小时计算）
     */
    public static long calculateWorkdayDuration(String startDateStr, String endDateStr) {
        LocalDateTime startDateTime = LocalDateTime.parse(startDateStr, DATE_TIME_FORMATTER);
        LocalDateTime endDateTime = LocalDateTime.parse(endDateStr, DATE_TIME_FORMATTER);
        return calculateWorkdayDuration(startDateTime, endDateTime);
    }

    /**
     * 计算两个 LocalDateTime 之间的工作日工期（排除周六和周日），返回毫秒值
     */
    public static long calculateWorkdayDuration(LocalDateTime startDateTime, LocalDateTime endDateTime) {
        // 开始时间晚于结束时间，返回0
        if (startDateTime.isAfter(endDateTime)) {
            return 0;
        }

        // 计算开始日期和结束日期
        LocalDate startDate = startDateTime.toLocalDate();
        LocalDate endDate = endDateTime.toLocalDate();

        // 计算总天数（包含开始和结束日期）
        long totalDays = ChronoUnit.DAYS.between(startDate, endDate) + 1;
        
        // 如果总天数为1天，直接计算当天的工作时间
        if (totalDays == 1) {
            return isWeekday(startDate) ? MILLISECONDS_PER_WORKDAY : 0;
        }

        // 计算工作日数量
        long workdays = 0;
        LocalDate currentDate = startDate;
        while (!currentDate.isAfter(endDate)) {
            if (isWeekday(currentDate)) {
                workdays++;
            }
            currentDate = currentDate.plusDays(1);
        }

        // 总工作日毫秒数 = 工作日天数+ * 每天毫秒数
        return workdays * MILLISECONDS_PER_WORKDAY;
    }

    /**
     * 判断是否为工作日（周一至周五）
     */
    private static boolean isWeekday(LocalDate date) {
        DayOfWeek day = date.getDayOfWeek();
        return day != DayOfWeek.SATURDAY && day != DayOfWeek.SUNDAY;
    }


    /**
     * 从最晚结束时间倒推（结束日期计入工期）计算最晚开始时间
     * @param lateFinishTime 最晚结束时间（格式：yyyy-MM-dd 23:59:59）
     * @param durationMillis 工期（毫秒数，8小时/天的整数倍）
     * @return 最晚开始时间（格式：yyyy-MM-dd 00:00:00）
     */
    public static LocalDateTime calculateLateStartFromMillis(LocalDateTime lateFinishTime, long durationMillis) {
        final long MILLIS_PER_WORK_DAY = 28800000L; // 8小时/天
        int workDays = durationMillis > 0 ? (int) (durationMillis / MILLIS_PER_WORK_DAY) : 0;

        if (workDays == 0) {
            return lateFinishTime.with(LocalTime.MIN);
        }

        // 关键修正：判断结束日期是否为工作日，若是则先扣1天工期（当天计入）
        DayOfWeek finishDay = lateFinishTime.getDayOfWeek();
        if (finishDay != DayOfWeek.SATURDAY && finishDay != DayOfWeek.SUNDAY) {
            workDays--; // 结束日是工作日，已算1天，剩余天数减1
        }

        // 从结束日的前一天开始倒推剩余天数
        LocalDateTime current = lateFinishTime.minusDays(1);
        int remainingDays = workDays;

        while (remainingDays > 0) {
            current = current.minusDays(1);
            DayOfWeek day = current.getDayOfWeek();
            if (day != DayOfWeek.SATURDAY && day != DayOfWeek.SUNDAY) {
                remainingDays--;
            }
        }

        return current.with(LocalTime.MIN);
    }



}